package pcmd;

use strict;
use warnings;

use Cwd;
use Cwd 'abs_path';
use File::Spec;
use File::Copy;
    
use pcmd_item;
use pcmd_gui;
use pcmd_fs;


#-------
# New --
#-------
sub new {
    my $arg0 = $_[0];
    my $cls = ref($arg0) || $arg0;
    
    my $self = {};
    bless $self, $cls;

    $self->init($_[1], $_[2]);
    
    return $self;
}


#--------------
# Init class --
#--------------
sub init {
    my $self = shift;

    # Load config
    $self->load_config();

    # Create gui
    $self->{'gui'} = pcmd_gui->new($self, $self->{'config'}->{'gui'}, $self->load_texts());

    # Get current dir
    $self->{conns} = {};
    $self->{conns}{fs} = pcmd_fs->new();
    
    if ($self->{conns}{fs}->connect()) {
        exit(1);
    };
        
    $self->{'left'} = {
        'conn' => 'fs',
        'directory' => '',
        'files' => [],
    };

    $self->{'right'} = {
        'conn' => 'fs',
        'directory' => '',
        'files' => [],
    };
    
    $self->change_dir('left', "$ENV{HOME}/tmp/");
    $self->change_dir('right', "$ENV{HOME}/tmp/");
};


#-------
# Run --
#-------
sub run {
    my $self = shift;

    $self->{'gui'}->run();
};


#---------------
# Load config --
#---------------
sub load_config {
    my $self = shift;

    my $gui_config = {
        'headers'       => ['name', 'ext', 'size', 'mtime'],
        'colors'        => {
            'background'    => 'white',
            'item_selected' => 'red',
            'item_normal'   => 'black',
        }
    };
    
    my $commands = {
        'text' => 'nedit',
    };

    $self->{'config'}->{'gui'} = $gui_config;
    $self->{'config'}->{'commands'} = $commands;

};


#--------------
# Load texts --
#--------------
sub load_texts {
    my $self = shift;

    my $texts = {
        'ok'                    => 'Ok',
        'error'                 => 'Error',
        'name'                  => 'Name',
        'ext'                   => 'Ext',
        'size'                  => 'Size',
        'mtime'                 => 'Mod. time',
        'curr_dir'              => 'Current directory',
        'new_folder'            => 'New folder',   
        't_remove_files'        => 'Remove files',   
        'l_remove_files'        => 'Do you really want to remove %d file(s)?',
        'c_remove_files'        => 'Remove not empty directories',
        't_confirm_copy'        => 'Confirm copy',   
        'l_confirm_copy'        => q|'%s' file is already exits. Do you want to overwrite it?|,
        'c_confirm_copy'        => 'Remove not empty directories',
    };

    return $texts;
};


#--------
# log  --
#--------
sub log {
    my $self = shift;
    my $type = shift;
    my $message = shift;

    if ($type eq 'error') {
        print STDERR "pcmd error    | $message\n";
        $self->{gui}->dialog_error_simple($message);
    } else {
        print STDERR "pcmd $type    | $message\n";        
    };
};


#---------------
# Update tab --
#---------------
sub update_tab {
    my $self = shift;
    my $tab = shift;

    my $array = [];
    my $error = $self->{conns}{$self->{$tab}{conn}}->get_file_list($self->{$tab}{directory}, undef, $array);

    unless ($error) {
        $self->{gui}->rebuild_tab($tab, $self->{$tab}{directory}, $array);
        $self->{$tab}{files} = $array;
    } else {
        $self->log('error', "$error");
    };
};


#--------------------
# Change directory --
#--------------------
sub change_dir {
    my $self = shift;
    my $tab = shift;
    my $path = shift;    

    my $array = [];
    my $error = $self->{conns}{$self->{$tab}{conn}}->get_file_list($path, undef, $array);

    unless ($error) {
        $self->{'gui'}->rebuild_tab($tab, $path, $array);
        $self->{$tab}{files} = $array;
        $self->{$tab}{directory} = $path;
    } else {
        $self->log('error', "$error");
    };
};


#--------------------
# Callback command --
#--------------------
sub callback_command {
    my $self = shift;
    my $tab = shift;
        
    my $idx = $self->{gui}->get_selected($tab);
   
    if ((defined $idx) and ($idx ne '')) {
        if ((defined $self->{$tab}{files}[$idx]) and ($self->{$tab}{files}[$idx]->get_type() eq 'dir')) {
            $self->change_dir($tab, $self->{$tab}{files}[$idx]->get_field('abs_path') );            
        };
    };
};


#------------------
# Callback title --
#------------------
sub callback_title {
    my $self = shift;
    my $tab = shift;
    my $dir = shift;
    
    my $item_idx = $self->{gui}->get_selected($tab);
    
    if ((defined $item_idx) and ($item_idx ne '')) {
        my $item = $self->{$tab}{curr_list}->[$item_idx];

        if ($item->get_type() eq 'dir') {
            my $path = $item->get_field('abs_path');
            
            $self->change_dir($tab, $path);

        } else {
            if (-T $item->get_field('abs_path')) {
                
            };            
            $item->print_stat();            
        };
    };
};


#---------------
# Callback F3 --
#---------------
sub callback_F3 {
    my $self = shift;
    
    my $tab = $self->{gui}->get_tab();
    my $item_idx = $self->{gui}->get_selected($tab);
    
    if ((defined $item_idx) and ($item_idx ne '')) {
        my $item = $self->{$tab}{curr_list}->[$item_idx];

        if ($item->get_type() eq 'dir') {

        } else {
            my $abs_path = $item->get_field('abs_path');
            if (system("$self->{config}{commands}{text} $abs_path &")) {
                 $self->log('error', "Could not exec: $!");
            };
        };
    };
};


#---------------
# Callback F5 --
#---------------
sub callback_F5 {
    my $self = shift;
    
    my $src_tab = $self->{gui}->get_tab();
    my $dst_tab = ($src_tab eq 'right') ? 'left' : 'right';
        
    
    use Switch;
    
    switch ($self->{$src_tab}{conn}) {
        case 'fs' {
            switch ($self->{$src_tab}{conn}) {
                case 'fs' {
                    $self->copy_fs2fs($src_tab, $dst_tab);
                };
            };            
        };        
    };
};


#---------------
# Callback F7 --
#---------------
sub callback_F7 {
    my $self = shift;
    
    # Get tab
    my $tab = $self->{gui}->get_tab();
    
    # Get new diretory name
    my $name = $self->{gui}->dialog_create_folder();
    
    if ((defined $name) and ($name ne '')) {
        
        my $error = $self->{conns}{$self->{$tab}{conn}}->create_dir($self->{$tab}{directory}, $name);
        
        unless ($error) {            
            $self->update_tab($tab);
        } else {
            $self->log('error', "$error");
        };
    };
};


#---------------
# Callback F8 --
#---------------
sub callback_F8 {
    my $self = shift;
    
    my $tab = $self->{gui}->get_tab();
    my @idxs = $self->{gui}->get_selection($tab);
    
    if (@idxs) {
        # 
        my $rmtree = 0;
        unless ($self->{gui}->dialog_remove(scalar(@idxs), \$rmtree)) {
            return;
        };
        
        # Init refresh
        my $refresh = 0;
        
        foreach my $idx (@idxs) {
            if (defined $self->{$tab}{files}[$idx]) {
                my $error = $self->{conns}{$self->{$tab}{conn}}->delete($self->{$tab}{directory}, $self->{$tab}{files}[$idx], $rmtree);
            
                unless ($error) {
                    $refresh = 1;
                } else {
                    $self->log('error', "$error");
                };
            };
        };
        
        # Refresh if needed
        if ($refresh) {
            $self->update_tab($tab);
        };
    };
};


#----------------
# Copy fs 2 fs --
#----------------
sub copy_fs2fs {
    my $self = shift;
    my $src_tab = shift;
    my $dst_tab = shift;

    my @selection = $self->{gui}->get_selection($src_tab);
    my $answer = '';
    
    foreach my $idx (@selection) {
        if (($idx ne '') and  (defined $self->{$src_tab}{files}[$idx])) {
            my $file = $self->{$src_tab}{files}[$idx];

            # Calculate destination path
            my $src_path =  $self->{$src_tab}{files}[$idx]->get_field('abs_path');
            my $dst_dir_path = $self->{conns}{$self->{$dst_tab}{conn}}->get_directory($self->{$dst_tab}{directory})->get_path();
            my $dst_path = File::Spec->catfile($dst_dir_path, $file->get_name());           
            
            # Check 
            if ((-e $dst_path) and ($answer ne 'Skip all') and ($answer ne 'Overwrite all')) {
                $answer = $self->{gui}->dialog_confirm_copy($dst_path);
            };
                        
            if ((not (-e $dst_path)) or ($answer eq 'Overwrite all') or ($answer eq 'Overwrite')) {
                unless (copy($src_path, $dst_path)) {
                    $self->log('error', "Error at copy $src_path -> $dst_path: $!");
                } else {
                    $self->{conns}{$self->{$dst_tab}{conn}}->get_directory($self->{$dst_tab}{directory})->add($dst_path);
                };
            };
        };
    };
    
    $self->update_tab($dst_tab);
};


1;

